#!/bin/sh

# Script to set MAC address for eth0 from uboot env

INTERFACE="eth0"
ENV_VAR="eth0_mac"
SCRIPT_NAME=$(basename "$0")

# Function to log messages
log_message() {
    echo "${SCRIPT_NAME}: $1"
}

# Function to get current MAC address from interface
get_current_mac() {
    local current_mac=$(ip link show "$INTERFACE" 2>/dev/null | grep -o -E '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}' | head -n 1)
    echo "$current_mac"
}

# Function to get MAC address from uboot env
get_mac_from_env() {
    local mac_addr=$(fw_printenv "$ENV_VAR" 2>/dev/null | cut -d'=' -f2)
    echo "$mac_addr"
}

# Function to save MAC address to uboot env
save_mac_to_env() {
    local mac_addr="$1"
    
    fw_setenv "$ENV_VAR" "$mac_addr" >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        log_message "Successfully saved MAC address '$mac_addr' to uboot env"
        return 0
    else
        log_message "Error: Failed to save MAC address to uboot env"
        return 1
    fi
}

# Function to perform the MAC address setting
do_set_mac() {
    log_message "Executing MAC address configuration for $INTERFACE..."

    # Check if required commands exist
    if ! command -v ip > /dev/null; then
        log_message "Error: 'ip' command not found"
        return 1
    fi

    if ! command -v fw_printenv > /dev/null || ! command -v fw_setenv > /dev/null; then
        log_message "Error: fw_printenv/fw_setenv commands not found"
        return 1
    fi

    # Check if interface exists
    if ! ip link show "$INTERFACE" >/dev/null 2>&1; then
        log_message "Error: Interface $INTERFACE not found"
        return 1
    fi

    # Get MAC address from uboot env or use current
    MAC_ADDR=$(get_mac_from_env)
    
    if [ -z "$MAC_ADDR" ]; then
        log_message "No MAC address in uboot env, using current MAC"
        MAC_ADDR=$(get_current_mac)
        
        if [ -z "$MAC_ADDR" ]; then
            log_message "Error: Cannot get current MAC address from $INTERFACE"
            return 1
        fi
        
        # Save current MAC to uboot env
        save_mac_to_env "$MAC_ADDR"
    else
        log_message "Found MAC address '$MAC_ADDR' in uboot env"
        
        # Validate MAC address format
        if ! echo "$MAC_ADDR" | grep -qE '^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$'; then
            log_message "Invalid MAC format in uboot env, using current MAC"
            MAC_ADDR=$(get_current_mac)
            if [ -z "$MAC_ADDR" ]; then
                log_message "Error: Cannot get current MAC address"
                return 1
            fi
            save_mac_to_env "$MAC_ADDR"
        fi
    fi

    # Check if MAC is already set
    CURRENT_MAC=$(get_current_mac)
    if [ "$CURRENT_MAC" = "$MAC_ADDR" ]; then
        log_message "MAC address '$MAC_ADDR' is already set on $INTERFACE"
        return 0
    fi

    # Set the MAC address
    log_message "Setting MAC address for $INTERFACE to $MAC_ADDR"
    ip link set dev "$INTERFACE" down
    ip link set dev "$INTERFACE" address "$MAC_ADDR"
    if [ $? -ne 0 ]; then
        log_message "Error: Failed to set MAC address"
        ip link set dev "$INTERFACE" up >/dev/null 2>&1
        return 1
    fi
    
    ip link set dev "$INTERFACE" up
    log_message "Successfully set MAC address for $INTERFACE to $MAC_ADDR"
    return 0
}

start() {
    log_message "Starting MAC address configuration..."
    do_set_mac
    # The exit status of do_set_mac will be the exit status of start() if needed,
    # but init scripts usually exit 0 unless there's a critical failure preventing boot.
}

stop() {
    log_message "Stop command received for MAC configuration. No action taken."
    # No specific action needed to "stop" a MAC address configuration.
    # The MAC address remains as set until next change or reboot.
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart|reload)
        log_message "Restart/Reload requested. Re-applying MAC configuration..."
        # For MAC setting, restart effectively means re-running the start logic.
        # No explicit stop action is taken before start.
        start
        ;;
    *)
        echo "Usage: $SCRIPT_NAME {start|stop|restart}"
        exit 1
        ;;
esac

exit $?